package com.zb.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.entity.ZjCodeField;
import com.zb.entity.ZjCodeFieldContent;
import com.zb.entity.ZjCodeUserRegisterFieldVal;
import com.zb.mapper.ZjCodeFieldMapper;
import com.zb.result.PageUtil;
import com.zb.service.ZjCodeFieldContentService;
import com.zb.service.ZjCodeFieldService;
import com.zb.service.ZjCodeUserRegisterFieldValService;
import com.zb.vo.CodeFieldContentVo;
import com.zb.vo.CodeFieldListVo;
import com.zb.vo.CodeFieldSelectVo;
import com.zb.vo.CodeFieldVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 编码字段表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2023-08-23
 */
@Service
public class ZjCodeFieldServiceImpl extends ServiceImpl<ZjCodeFieldMapper, ZjCodeField> implements ZjCodeFieldService {
    @Resource
    private ZjCodeFieldMapper codeFieldMapper;
    @Resource
    private ZjCodeFieldContentService fieldContentService;
    @Resource
    private ZjCodeUserRegisterFieldValService codeUserRegisterFieldValService;

    // 新增或修改编码字段
    @Override
    @Transactional
    public void save(Long custAccId, CodeFieldVo codeFieldVo) {
        Assert.isTrue(null == codeFieldMapper.existByName(custAccId, codeFieldVo.getType(), codeFieldVo.getCategory(), codeFieldVo.getId(), codeFieldVo.getName()),
                "字段名称已重复！", codeFieldVo.getName());
        ZjCodeField codeField = new ZjCodeField();
        BeanUtils.copyProperties(codeFieldVo, codeField);
        codeField.setDisabled(codeFieldVo.getStatus());
        if (null != codeField.getId()) {
            this.updateById(codeField);
        } else {
            codeField.setId(IdWorker.getId());
            codeField.setCustAccId(custAccId);
            this.save(codeField);
        }
        fieldContentService.save(custAccId, codeField.getId(), codeFieldVo.getContentVos(), codeFieldVo.getDelContentVoIds());
    }

    // 获取编码字段列表
    @Override
    public Map<String, Object> getList(Long custAccId, CodeFieldSelectVo selectVo) {
        QueryWrapper<ZjCodeField> wrapper = new QueryWrapper<>();
        wrapper.eq("cust_acc_id", custAccId).eq("category", selectVo.getCategory());
        if (null != selectVo.getType()) {
            wrapper.eq("type", selectVo.getType());
        }
        if (StringUtils.isNotBlank(selectVo.getName())) {
            wrapper.like("name", selectVo.getName());
        }
        PageUtil.setPageLimit(selectVo);
        Page<ZjCodeField> page = this.page(new Page<>(selectVo.getPage(), selectVo.getLimit()), wrapper);

        List<ZjCodeFieldContent> fieldContentList = fieldContentService.getByCodeFieldIds(page.getRecords().stream().map(ZjCodeField::getId).toList());
        List<CodeFieldListVo> voList = page.getRecords().stream().map(field -> {
            CodeFieldListVo vo = new CodeFieldListVo();
            BeanUtils.copyProperties(field, vo);
            vo.setStatus(field.getDisabled());
            vo.setContent(fieldContentList.stream().filter(con -> Objects.equals(field.getId(), con.getCodeFieldId())).map(ZjCodeFieldContent::getVal).collect(Collectors.joining("、")));
            return vo;
        }).toList();
        return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), voList);
    }

    // 根据ID获取编码字段详情
    @Override
    public CodeFieldVo getInfo(Long id) {
        ZjCodeField field = this.getById(id);
        Assert.isTrue(null != field, "编码字段参数[" + id + "]的数据不存在！");
        CodeFieldVo vo = new CodeFieldVo();
        BeanUtils.copyProperties(field, vo);
        vo.setStatus(field.getDisabled());
        vo.setContentVos(fieldContentService.getByCodeFieldId(id).stream().map(content -> {
            CodeFieldContentVo contentVo = new CodeFieldContentVo();
            BeanUtils.copyProperties(content, contentVo);
            return contentVo;
        }).toList());
        return vo;
    }

    // 批量更改是否移动端显示选项
    @Override
    public void updateMobileShowBatchByIds(List<Long> idList, boolean mobileShow) {
        codeFieldMapper.updateMobileShowBatchByIds(idList, mobileShow);
    }

    // 批量更改是否列表显示选项
    @Override
    public void updateListShowBatchByIds(List<Long> idList, boolean listShow) {
        codeFieldMapper.updateListShowBatchByIds(idList, listShow);
    }

    // 批量更改列表显示查询条件选项
    @Override
    public void updateListConditionBatchByIds(List<Long> idList, boolean listCondition) {
        codeFieldMapper.updateListConditionBatchByIds(idList, listCondition);
    }

    // 批量更改编码字段状态
    @Override
    public void updateDisabledBatchByIds(List<Long> idList, boolean status) {
        codeFieldMapper.updateDisabledBatchByIds(idList, status);
    }

    // 批量删除编码字段
    @Override
    public void deleteBatchByIds(List<Long> idList) {
        QueryWrapper<ZjCodeUserRegisterFieldVal> userRegisterFieldValQueryWrapper = new QueryWrapper<>();
        userRegisterFieldValQueryWrapper.select("code_field_id");
        userRegisterFieldValQueryWrapper.in("code_field_id", idList);
        userRegisterFieldValQueryWrapper.last("limit 10");
        List<ZjCodeUserRegisterFieldVal> userRegisterFieldValList = codeUserRegisterFieldValService.list(userRegisterFieldValQueryWrapper);
        if (CollectionUtil.isNotEmpty(userRegisterFieldValList)) {
            QueryWrapper<ZjCodeField> wrapper = new QueryWrapper<>();
            wrapper.select("name");
            wrapper.in("id", userRegisterFieldValList.stream().map(ZjCodeUserRegisterFieldVal::getCodeFieldId).distinct().toList());
            List<ZjCodeField> fieldList = this.list(wrapper);
            Assert.isTrue(false, "编码字段名称[ " + fieldList.stream().map(ZjCodeField::getName).collect(Collectors.joining("、")) + " ]已被关联使用，不允许删除");
        }
        fieldContentService.deleteByCodeFields(idList);
        this.removeByIds(idList);
    }


}
